package com.zimmur.service.impl;
import java.util.HashMap;
import java.util.Map;

import javax.annotation.Resource;

import org.apache.zookeeper.Login;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import com.zimmur.common.ConstData;
import com.zimmur.common.EnumPointRule;
import com.zimmur.common.ReturnJsonEntity;
import com.zimmur.common.StatusCodeEnum;
import com.zimmur.dao.IAccountInfoDao;
import com.zimmur.dao.IUserDao;
import com.zimmur.model.account.AccountInfo;
import com.zimmur.model.account.GoodsUser;
import com.zimmur.model.account.User;
import com.zimmur.model.dto.UserDTO;
import com.zimmur.service.IUserService;
import com.zimmur.service.RedisCacheUtil;
import com.zimmur.service.account.IPointLogService;
import com.zimmur.service.account.IUserNewMessageService;
import com.zimmur.service.order.ICartService;
import com.zimmur.service.order.IWishListService;
import com.zimmur.tenpay.util.MD5;
import com.zimmur.tools.JwtTokenUtil;
import com.zimmur.tools.PublicKey;
 
  
@Service("userService")  
public class UserServiceImpl implements IUserService {  
	private static Logger log=LoggerFactory.getLogger(UserServiceImpl.class);
    @Resource  
    private IUserDao userDao;  
    
    @Resource
    private IAccountInfoDao acccountInfoDao;
    @Resource
	private ICartService cartService;
    @Resource
    private IPointLogService pointLogService;
    @Resource
	private IWishListService wishListService;
	@Resource
	private IUserNewMessageService userNewMessageService;
	@Resource
	private RedisCacheUtil<String> redis;
	@Resource
	private JwtTokenUtil jwtTokenUtil;
	@Value("${public.key}")
	private String publicKey;
    
    public ReturnJsonEntity login(String account,String password,String deviceId,String platForm){
    	ReturnJsonEntity entity = new ReturnJsonEntity();
    	StatusCodeEnum statusCodeEnum = StatusCodeEnum.CODE100000;
    	User user = getUserInfoByUserName(account,platForm);
        
        if(user != null){
			if (!StringUtils.isEmpty(password) 
					&& !MD5.MD5Encode(password).equals(user.getUserPwd())) {
				statusCodeEnum = StatusCodeEnum.CODE200100;
				entity.setCode(statusCodeEnum.getCode());
				entity.setMsg(statusCodeEnum.getMsg());
				return entity;
			}
			statusCodeEnum = StatusCodeEnum.CODE000000;
    		String token = getUserToken(user);
    		user.setAuthCode(token);
    		//获取公钥
    		String Key=PublicKey.getKey(redis, publicKey);
    		user.setPublicKey(Key);
			if (!StringUtils.isEmpty(deviceId) 
					&& !StringUtils.isEmpty(user.getDeviceId())
					&& !deviceId.equals(user.getDeviceId())) {
				statusCodeEnum = StatusCodeEnum.CODE200101;
				user.setDeviceId(deviceId);
			}
    		//begin 积分规则处理
    		EnumPointRule pointRule = EnumPointRule.ZK_LOGIN;
    		if(user.getCategoryCode().equals("xk"))
    			pointRule = EnumPointRule.XK_LOGIN;
    		
    		pointLogService.mainPointLog(Long.parseLong(user.getUserId()), "用户登录", pointRule, 0);
    		//end 积分规则
    		user.setMessageNum(userNewMessageService.selectNoReadMessageNum(Long.parseLong(user.getUserId())));
    		entity.setData(user);
    		entity.setCode(statusCodeEnum.getCode());
        	entity.setMsg(statusCodeEnum.getMsg());
        }else{
        	statusCodeEnum = StatusCodeEnum.CODE200100;
        	entity.setCode(statusCodeEnum.getCode());
        	entity.setMsg(statusCodeEnum.getMsg());
        }
        return entity;
    }
    
	@Override
	public User getUserInfoByUserName(String userName,String platForm) {
		User user = null;
		if(platForm.equals("wx")){
			user = this.userDao.selectUserInfoByWxID(userName);
		}else if (platForm.equals("wb")) {
			user = this.userDao.selectUserInfoByWbID(userName);
		}else{
			user = this.userDao.selectUserInfoByUserName(userName); 
		}
		if(user!=null){
			user.setCartItemNum(cartService.countUserCart(Long.parseLong(user.getUserId())));
			user.setCartItemJe(cartService.countUserCartAmount(Long.parseLong(user.getUserId())));
			user.setWishNum(wishListService.queryWishNumByUserId(Long.parseLong(user.getUserId())));
		}
		return user;
	}
	
	
	@Override
	public String getUserToken(User user){
		String token = redis.getHashMap(ConstData.REDIS_USERLOGIN_PREFIX, user.getUserId());
		if(token == null || StringUtils.isEmpty(token)){
			token = reCreateAuthToken(user.getUserId(),user.getUserName());
			user.setAuthCode(token);
			updateUserToken(user);
		}else{
			UserDTO userDTO = jwtTokenUtil.parse(token);
			if(userDTO == null){
				token = reCreateAuthToken(user.getUserId(),user.getUserName());
				user.setAuthCode(token);
				updateUserToken(user);
			}
		}
		return token;
	}
	
	private String reCreateAuthToken(String userId, String userName) {
		UserDTO userDTO = new UserDTO(userId, userName);
		return jwtTokenUtil.create(userDTO);
	}
	
	@Override
	public boolean updateUserToken(User user) {
		String authCode = user.getAuthCode();
		if(user==null || StringUtils.isEmpty(authCode))
			return false;
		try {
			redis.setHashMap(ConstData.REDIS_USERLOGIN_PREFIX, user.getUserId(), authCode);
			return true;
			
		} catch (Exception e) {
			log.error("updateUserToken Error",e);
		}
		return false;
	}
	
	@Override
	public void delUserToken(String userId){
		redis.delHashMap(ConstData.REDIS_USERLOGIN_PREFIX, userId);
	}
	
	@Override
	public Long getUserIdByToken(String token) {
		return jwtTokenUtil.getUserId(token);
	}

	@Transactional
	public boolean registerUser(User user,String openId, String platForm) {
		boolean bRet = false;
		try {
			if(platForm.equals("wx")){
				user.setWxOpenId(openId);
			}else if(platForm.equals("wb")){
				user.setWbOpenId(openId);
			}
			if(!user.getInviteCode().equals("")){
				User inviteUser = userDao.selectUserInfoByInviteCode(user.getInviteCode());
				if(inviteUser!=null)
					user.setIsApply(1);
			}
			int iRet = userDao.insert(user);
			if(iRet>0){
				AccountInfo accountInfo = new AccountInfo();
				accountInfo.setUserId(Long.parseLong(user.getUserId()));
				accountInfo.setCurJe(0.0);
				accountInfo.setCurPoint(0);
				acccountInfoDao.insert(accountInfo);
				bRet=true;
			}
		} catch (Exception e) {
			log.error(e.getMessage());
		}
		
		return bRet;
	}


	@Override
	public User getUserInfoByUserId(long userId) {
		User user = userDao.selectUserInfoByUserId(userId);
		if(user!=null){
			user.setAuthCode(getUserToken(user));
			user.setCartItemNum(cartService.countUserCart(Long.parseLong(user.getUserId())));
			user.setCartItemJe(cartService.countUserCartAmount(Long.parseLong(user.getUserId())));
			user.setWishNum(wishListService.queryWishNumByUserId(Long.parseLong(user.getUserId())));
		}
		return user;
	}


	@Override
	public boolean updateUserTopicNum(long userId) {
		return userDao.updateUserTopicNum(userId)>0?true:false;
	}

	@Override
	public boolean updateUserFollowNum(long userId, int num) {
		if(num>1)
			return false;
		User user = userDao.selectUserInfoByUserId(userId);
		
		if (user == null) {
			return false;
		}
		int curFllowNum = user.getFollowNum();
		if(num<0 && curFllowNum <= 0){
			return false;
		}
		
		Map<String, Object> map = new HashMap<>();
		if(num>0){
			map.put("followNum", curFllowNum+1);
		}else{
			map.put("followNum", curFllowNum-1);
		}
		map.put("userId", userId);
		return userDao.updateUserFollowNum(map)>0?true:false;
	}


	@Override
	public GoodsUser selectByUserId(long userId) {
		return userDao.selectGoodsUserByUserId(userId);
	}


	@Override
	public GoodsUser selectGoodsIsConcern(long createUser, long userId) {
		return userDao.selectGoodsIsConcern(createUser, userId);
	}
	@Override
	public GoodsUser selectTopicIsConcern(long createUser, long userId,Integer userType) {
		return userDao.selectTopicIsConcern(createUser, userId, userType);
	}


	@Override
	public int updateUserinfo(User user) {
		return userDao.updateUserinfo(user);
	}


	@Override
	public int updateUserUserPwd(User user) {
		return	userDao.updateUserPwd(user);
	}


	@Override
	public Long selectUserNameAndUserPwd(User user) {
		return userDao.selectUserNameAndUserPwd(user);
	}


	@Override
	public User selectUserIdAndUserPwd(User user) {
		return userDao.selectUserIdAndUserPwd(user);
	}


	@Override
	public Long selectByUserNameAndMobileNo(User user) {
		return userDao.selectByUserNameAndMobileNo(user);
	}


	@Override
	public boolean weiboUserCanelAuthor(String uid) {
		return userDao.updateCanelWeiboUid(uid)>0?true:false;
	}
  
}  
